/*
** server.h for Server in /home/vriely/Dropbox/work/Unix/Zappy_none/serv-src
**
** Made by Samuel Vrielynck
** Login   <vriely_s@epitech.net>
**
** Started on  Wed May 16 20:06:40 2012 Samuel Vrielynck
** Last update Thu Jul 19 22:05:01 2012 guillaume renard
*/

#ifndef			SERVER_H
#define			SERVER_H

#include		<sys/time.h>
#include		<sys/types.h>
#include		<sys/stat.h>
#include		<fcntl.h>
#include		<unistd.h>
#include		<stdio.h>

#include		"string.h"
#include		"list.h"

/**********/
/* Define */
/**********/
#define MAX_CLIENT	1000000
#define	MILLI	       	1000000

#define UP     		1
#define RIGHT  		2
#define DOWN		3
#define LEFT		4

#define BIT		1052945

#define NB_OBJECT	7
#define	DROP_RATE	50

#define FOOD_TIMER(x)	(126 * MILLI / x)

/********/
/* Enum */
/********/
typedef enum
{
  FOOD,
  LINEMATE,
  DERAUMERE,
  SIBUR,
  MENDIANE,
  PHIRAS,
  THYSTAME,
  JOUEUR
}			e_ressource;

typedef enum
{
  FORK,
  INCATATION,
  BROADCAST,
  EXPULSE
}			e_event;

typedef enum
{
  CONNECT_MNT,
  EXPULSE_MNT,
  INCANT_MNT,
  INVENT_MNT,
  LEVEL_MNT
}			e_event_mnt;

typedef enum
{
  UNKNOWN,
  NORD,
  EST,
  SUD,
  OUEST
}			e_dir;

/*************/
/* Structure */
/*************/
typedef struct		s_fd
{
  fd_set		wfds;
  fd_set		rfds;
}			t_fd;

typedef struct		s_coord
{
  unsigned int		x;
  unsigned int		y;
}			t_coord;

typedef struct		s_team
{
  char			*name;
  unsigned char		id;
  unsigned int		nb_player;
  unsigned int		nb_maxlvl;
  unsigned int		slot;
  void			(*check_slot)(struct s_team*, unsigned int);

  t_list		*egg;
}			t_team;

typedef struct		s_egg
{
  unsigned int		id;
  long unsigned int	action;

  t_coord		coord;
}			t_egg;

typedef struct		s_gamer
{
  unsigned char		direction;
  unsigned char		level;
  unsigned int		action;
  unsigned int		food;

  char			*action_str;
  int			inventory[NB_OBJECT];
  t_coord		coord;
  t_list		*task;
  t_team		*team;
}			t_gamer;

typedef struct		s_client
{
  int			sock;
  t_string		*send;
  t_string		*rcv;

  t_gamer		*gamer;
}			t_client;

typedef struct		s_inventory
{
  int			inv[NB_OBJECT + 1];
}			t_inventory;

typedef struct		s_game
{
  int			serverfd;
  unsigned int		time;
  long unsigned int	sleep;
  unsigned int		maxfd;
  const char		*port_index;
  int			nb_player;

  t_client		*graphic;
  t_coord		coord;
  t_list		*team;
  t_list		*event;
  t_list		*event_mnt;
  t_inventory		**obj;
  char			drop_rate[100];
}			t_game;

typedef struct		s_broadcast
{
  char			*message;

  t_client		*client;
  t_coord		coord;
}			t_broadcast;

typedef struct		s_incantation
{
  t_coord		coord;
  t_client		*client;

  unsigned char		lvl;
  unsigned char		ok;
}			t_incantation;

typedef struct		s_expulse
{
  t_client		*client;
}			t_expulse;

typedef struct		s_fork
{
  int			id;
  int			status;

  t_coord		coord;
  t_client		*client;
}			t_fork;

typedef struct		s_mov
{
  int			x;
  int			y;
  int			movX;
  int			movY;
  int			sizeX;
  int			sizeY;
}			t_mov;

typedef struct		s_event
{
  e_event		type;
  long unsigned int	action;
  void			*data;
}			t_event;

/***********************/
/* Tableau de pointeur */
/***********************/
typedef struct		s_handle_event
{
  e_event		type;
  char			(*func)(t_event *, t_game *, t_list *, long unsigned int);
}			t_handle_event;

typedef struct		s_game_fun
{
  char			*name;
  char			*(*func)(t_client *, t_game *);
  unsigned int		len;
}			t_game_fun;

typedef struct		s_inven_func
{
  char			*name;
  e_ressource		type;
}			t_inven_func;

typedef struct		s_func_mov
{
  void			(*f)(t_game *, t_gamer *);
}			t_func_mov;

typedef struct		s_handle_event_mnt
{
  e_event_mnt		type;
  char			(*func)(t_game *, t_list *, t_event *);
}			t_handle_event_mnt;

typedef struct		ptr_pars
{
  char			*cmd;
  int			(*cmdfct)(const char *argv[], unsigned int *, t_game *);
}			t_pars;

typedef struct		ptr_monitor
{
  char			*cmd;
  void			(*cmdfct)(t_client *client, t_game *game, char *cmd);
}			t_monitor;

typedef struct		ptr_serv_monitor
{
  char			*cmd;
  void			(*cmdfct)(t_client *client, t_game *game, t_client *graphic);
}			t_serv_monitor;

typedef struct		ptr_dir
{
  e_dir			dir;
  void			(*ptrfct)(t_game *, t_gamer *, t_mov, t_string *);
}			t_dir;

/********/
/* Init */
/********/
int			init(const char *);
t_game			*new_game();
char			check_food(t_game *game, t_client *, long unsigned int);

/********/
/* Exec */
/********/
void			exec(t_game *);

/**********/
/* Client */
/**********/
void			check_client(t_list *, t_fd *, t_game *,
    long unsigned int);
void			erase_client(void *);
void			check_team_graph(t_game *game, t_client *client);
void			check_team_egg_slot(t_client *, t_team *, t_game *);
void			check_team_slot(t_client *client,
    t_team *team, t_game *game);

/********/
/* Team */
/********/
t_team			*new_team(const char *);
void			check_team_concat(t_client *client,
    struct s_team *team, t_game *game);
int			check_winner_egg(t_list *, long unsigned int);

/*********/
/* Gamer */
/*********/
void			play(t_client *, t_game *, long unsigned int);
t_gamer			*new_gamer(t_team*, int, int);
t_gamer			*new_gamer_init(t_team *, t_coord);
void			move_player(t_game *, t_gamer *, unsigned char);

char			*inventaire(t_client *, t_game *);
char			*pose(t_client *, t_game *);
char			*prend(t_client *, t_game *);
char			*connect_nbr(t_client *, t_game *);

char			orientation(char, char);
char			*broadcast(t_client *, t_game *);
char			*pond(t_client *, t_game *);
char			*incantation(t_client *, t_game *);
char			*expulse(t_client *, t_game *);

/**************/
/* Incantation*/
/**************/
void			foreach_inc_lvl(void *, void *);
void			foreach_inc_fail(void *, void *);

/**********/
/* Object */
/**********/
char			*gere_ressource(t_gamer *, t_game *, char, e_ressource);
void			drop_obj(t_game *game, long unsigned int);
void			free_obj(t_game *game);

/*********/
/* Clear */
/*********/
void			clear_team(void *);
void			erase_client(void *);
void			delete_game(t_game *);
void			erase_event_mnt(void *);
struct s_item		*kill_client(t_list *, t_client *, t_game *, t_item *);

/********/
/* Time */
/********/
long unsigned int	init_before_exe(t_game *, struct timeval *);
void			getsleeptime(long unsigned int *, unsigned long int);

/*************/
/* Xfunction */
/*************/
void			xclose(int);
FILE			*xfopen(char *, char *);
void			*xcalloc(size_t, size_t);
void			xfclose(FILE *);
void			*xmalloc(size_t size);
int			xread(int, void *, size_t);

/*********/
/* Event */
/*********/
t_event			*new_event(e_event, long unsigned int, void *);

t_expulse		*new_expulse(t_client *);
t_broadcast		*new_broadcast(t_coord, char *, t_client *);
t_incantation		*new_incantation(t_coord, unsigned char, t_client *,
    unsigned char);
t_fork			*new_fork(t_coord, t_client *);

char			is_alive(unsigned int, t_gamer, long unsigned int);

void			check_event_mnt(t_list *, t_game *);
char			handle_connect_mnt(t_game *, t_list *, t_event *);
char			handle_expulse_mnt(t_game *, t_list *, t_event *);
char			handle_incant_mnt(t_game *, t_list *, t_event *);
char			handle_invent_mnt(t_game *, t_list *, t_event *);
char			handle_level_mnt(t_game *, t_list *, t_event *);

/*************/
/* t_expulse */
/*************/
void			check_event(t_list *, t_game *, long unsigned int);

char			handle_broadcast(t_event *, t_game *, t_list *,
    long unsigned int);
char			handle_inca(t_event *, t_game *, t_list *,
    long unsigned int);
char			handle_fork(t_event *, t_game *, t_list *,
    long unsigned int);
char			handle_expulse(t_event *, t_game *, t_list *,
    long unsigned int);

/*************/
/* Conf file */
/*************/
int			*getConf();

/****************/
/* Strtowordtab */
/****************/
char			**getTab(const char *line, const char del);
void			freetab(char **);

/**********/
/* Parser */
/**********/
int			add_team(const char *argv[], unsigned int *, t_game *);
int			init_x(const char *argv[], unsigned int *, t_game *);
int			init_y(const char *argv[], unsigned int *, t_game *);
int			init_time(const char *argv[], unsigned int *, t_game *);
int			init_port(const char *argv[], unsigned int *, t_game *);
int			init_client(const char *argv[], unsigned int *, t_game *);

t_egg			*new_egg(unsigned int, t_coord, unsigned int);

/***************/
/* Look_player */
/***************/
char			*look_player(t_game *, t_gamer *);

/************/
/* Move_map */
/************/
t_inventory		move_map_n(t_inventory **, t_mov *, int, int);

/******************/
/* Initialisation */
/******************/
void			init_game(t_game *);

void			gere_task(t_client *, t_game *);

/***********/
/* Monitor */
/***********/
void			cmd_monitor(char *cmd, t_client *client, t_game *game);
void			msz(t_client *client, t_game *game, char *cmd);
void			bct(t_client *client, t_game *game, char *cmd);
void			mct(t_client *client, t_game *game, char *cmd);
void			tna(t_client *client, t_game *game, char *cmd);
void			ppo(t_client *client, t_game *game, char *cmd);
void			plv(t_client *client, t_game *game, char *cmd);
void			pin(t_client *client, t_game *game, char *cmd);
void			sgt(t_client *client, t_game *game, char *cmd);
void			sst(t_client *client, t_game *game, char *cmd);

/******************/
/* Server Monitor */
/******************/
void			serv_monitor(char *, t_client *, t_game *, t_client *);
void			serv_ppo(t_client *, t_game *, t_client *);
void			serv_pin(t_client *, t_game *, t_client *);
void			serv_pnw(t_client *, t_game *, t_client *);
void			serv_bct(t_client *, t_game *, t_client *);
void			serv_pdi(t_client *, t_game *, t_client *);
void			serv_pfk(t_client *, t_game *, t_client *);
void			serv_pic(t_client *, t_game *, t_client *);
void			send_data_incan(t_client *, t_incantation *, int);

#endif /* end of include guard: SERVER_H */
